<?php

namespace App\Library;

use App\Models\IntegralKill;
use App\Models\Integrallist;
use App\Models\MallOrder;
use App\Models\User;
use App\Models\UserCoupons;
use Exception;

/**
 * 处理积分兑换流程(调用必须放在事务中)
 *
 * $exchange = new HandleIntegralExchange($user_id, $kill_id,$num);
 * $res = $exchange->entry();
 * if($res != 'success') {
 *     throw new Exception($res);
 * }
 */
class HandleIntegralExchange
{
    private $user;
    private $kill;
    private $num;
    private $order_id;

    public function __construct($user_id, $kill_id, $num = 1)
    {
        $this->user = User::where(['userID' => $user_id])->first();
        $this->kill = IntegralKill::where(['kill_id' => $kill_id])->first();
        $this->num  = $num;
    }

    /**
     * 积分兑换入口
     * @param  [type]  $user_id [用户id]
     * @param  [type]  $kill_id [积分商品id]
     * @param  integer $num     [兑换数量]
     * @return [type]           [操作提示]
     */
    public function entry()
    {
        try {
            $status = 0;
            $data   = [];
            //验证用户id
            $this->checkUser();
            //验证积分商品id
            $this->checkIntegralKill();
            //验证积分
            $this->checkIntegral();
            //验证商品是否过期
            //$this->checkIntegralTime();
            //验证商品库存
            $this->checkIntegralNum();
            //存入积分订单表
            $order = MallOrder::create([
                'user_id'         => $this->user->userID,
                'kill_id'         => $this->kill->kill_id,
                'goods_id'        => $this->kill->goods_id,
                'goods_type'      => $this->kill->goods_type,
                'integral'        => $this->kill->integral,
                'record_id'       => null,
                'order_type'      => 1, //积分兑换
                'order_status'    => 1,
                'address_id'      => 0,
                'order_num'       => getOrderNum(),
                'postage'         => 0,
                'delivery_type'   => 0,
                'pay_type'        => 0,
                'pay_time'        => time(),
                'delivery_number' => null,
                'send_firm'       => null,
                'send_time'       => null,
                'create_time'     => time(),
                'is_delete'       => 0,
            ]);

            //如果兑换的是优惠券，存入用户优惠券领取记录表
            if ($this->kill->goods_type == 2) {
                UserCoupons::create([
                    'order_id'    => $order->order_id,
                    'user_id'     => $this->user->userID,
                    'coupon_id'   => $this->kill->goods_id,
                    'is_used'     => 0,
                    'use_time'    => null,
                    'create_time' => time(),
                    'is_delete'   => 2,
                    'fail_time'   => $this->kill->end_time,
                ]);
            }
            //存入积分消费表
            Integrallist::create([
                'userID'   => $this->user->userID,
                'integral' => $this->kill->integral,
                'type'     => 2,
                'property' => 5,
                'id'       => $order->order_id,
                'note'     => '积分兑换消耗' . $this->kill->integral . '积分',
                'time'     => time(),
            ]);
            //减掉库存记录
            IntegralKill::where(['kill_id' => $this->kill->kill_id])->decrement('num', $this->num);
            //扣除用户消耗的积分
            User::where(['userID' => $this->user->userID])->decrement('integral', $this->kill->integral);

            $status           = 1;
            $msg              = 'success';
            $data['order_id'] = $order->order_id;
        } catch (Exception $e) {
            $msg = $e->getMessage();
        }

        return ['status' => $status, 'msg' => $msg, 'data' => $data];
    }

    private function checkUser()
    {
        if (count($this->user) == 0) {
            throw new Exception('用户不存在');
        }
    }

    private function checkIntegralKill()
    {
        if (count($this->kill) == 0) {
            throw new Exception('商品不存在');
        }
    }

    private function checkIntegral()
    {
        if ($this->user->integral < $this->kill->integral) {
            throw new Exception('积分余额不足兑换！');
        }
    }

    private function checkIntegralTime()
    {
        if ($this->kill->bg_time > time() || $this->kill->end_time < time()) {
            throw new Exception('该商品不在兑换期内');
        }
    }

    private function checkIntegralNum()
    {
        if ($this->kill->num < $this->num) {
            throw new Exception('库存不足');
        }
    }
}
